#include "UltimatePhysXPrecompiled.h"
#include "UltimatePhysXActor.h"


UltimatePhysXActor::UltimatePhysXActor(void)
{
}


UltimatePhysXActor::~UltimatePhysXActor(void)
{
}

void UltimatePhysXActor::setNxActor(NxActor* actor)
{
	nxActor = actor;
}

NxActor* UltimatePhysXActor::getNxActor()
{
	return nxActor;
}


void UltimatePhysXActor::setGlobalPosition(Ogre::Vector3 position)
{

	nxActor->moveGlobalPosition(NxVec3(position.x, position.y , position.z));

}

Ogre::Vector3 UltimatePhysXActor::getGlobalPosition()
{
	return Ogre::Vector3(nxActor->getGlobalPosition().x, nxActor->getGlobalPosition().y, nxActor->getGlobalPosition().z);
}

void UltimatePhysXActor::setGlobalOrientation(Ogre::Quaternion orientation)
{
	nxActor->moveGlobalOrientation(NxQuat(NxVec3(orientation.x,orientation.y,orientation.z),orientation.w));

}

Ogre::Quaternion UltimatePhysXActor::getGlobalOrientation()
{
	return Ogre::Quaternion(nxActor->getGlobalOrientationQuat().w, nxActor->getGlobalOrientationQuat().x, nxActor->getGlobalOrientationQuat().y,nxActor->getGlobalOrientationQuat().z);
}



void UltimatePhysXActor::setLookAt(Ogre::Vector3 target)
{

	NxQuat initOri = nxActor->getGlobalOrientationQuat();
	NxVec3 initDir = initOri.rot(NxVec3(1,0,0));

	initDir.normalize();

	NxVec3 dir =NxVec3(target.x,target.y,target.z)- nxActor->getGlobalPosition();
	dir.normalize();

	NxVec3 axis = initDir.cross(dir);
	float cosAng = initDir.dot(dir);
		

	float ang = acos(cosAng);
	Ogre::Radian radian = Ogre::Radian(ang);
	float angDeg = radian.valueDegrees();

	NxQuat newRot = NxQuat(angDeg , axis);
	nxActor->moveGlobalOrientationQuat(newRot*initOri);

	/*NxQuat newOri = actor->getGlobalOrientationQuat();
	NxVec3 newDir = newOri.rot(NxVec3(1,0,0));*/


}
	
Ogre::Vector3 UltimatePhysXActor::getFacingDir()
{
	NxQuat initOri = nxActor->getGlobalOrientationQuat();
	NxVec3 initDir = initOri.rot(NxVec3(1,0,0));
	initDir.normalize();


	return Ogre::Vector3(initDir.x, initDir.y, initDir.z);
}


void UltimatePhysXActor::addForce(Ogre::Vector3 force)
{
	/*actor->setLinearVelocity(NxVec3(0,0,0));
	actor->setAngularVelocity(NxVec3(0,0,0));*/
	nxActor->addForce(NxVec3(force.x,force.y,force.z));
}

void UltimatePhysXActor::addTorque(Ogre::Vector3 torque)
{
	/*actor->setLinearVelocity(NxVec3(0,0,0));
	actor->setAngularVelocity(NxVec3(0,0,0));*/
	nxActor->addTorque(NxVec3(torque.x, torque.y, torque.z));
}


void UltimatePhysXActor::setUserData(void * data)
{
	userData = data;
	//nxActor->userData = data;
}

void * UltimatePhysXActor::getUserData(void)
{
	return userData;
	//return nxActor->userData;
}

void UltimatePhysXActor::disableGravity()
{
	nxActor->raiseBodyFlag(NX_BF_DISABLE_GRAVITY);

}

void UltimatePhysXActor::setGroup(int i)
{
	nxActor->setGroup(i);
}

int UltimatePhysXActor::getGroup()
{
	return nxActor->getGroup();
}

void UltimatePhysXActor::setKinematic(bool isKinematic)
{
	if(isKinematic)
	{
		nxActor->raiseBodyFlag(NX_BF_KINEMATIC);
	}
	else
	{
		nxActor->clearBodyFlag(NX_BF_KINEMATIC);
	}
}